/*
 * handleThread.c
 *
 *  Created on: 2010-3-11
 *      Author: abc
 */
#include <netdb.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <arpa/inet.h>

#include "clientInfoList.h"
#define   MAXBUF   256

extern pclientinfo clientlink;
extern int   port;
extern char  *  multicast_addr;

void getOwnIP(char* netdevice){
          int inet_sock;
          struct ifreq ifr;
          FILE *net_devs;
          char buf[1024];
          char interface[32];
          int index;

          net_devs = fopen("/proc/net/dev", "r");
          if(net_devs == NULL){
                  perror("Can't open /proc/net/dev for reading");
                  exit(1);
          }

          inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
          while(1){
                  if(fscanf(net_devs, "%32s %1024[^\n]", interface, buf) <= 0){
                          break;
                  }
                  index = 0;
                  while ( index<32 && interface[index] != ':' ) {
                          index++;
                  }
                  if (index>=32)
                          continue;
                  interface[index] = '\0';
                  strcpy(ifr.ifr_name, interface);
                  if (ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0)
                          perror("ioctl");
                  //printf("%s:\t%s\n", interface,inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));
                  if(strcmp(netdevice,interface)==0){
                    strcpy(netdevice,inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));
                  }
          }
          close(inet_sock);



}
void * multiThread(void* p){
	  int   s;
	  struct   sockaddr_in   srv;
	  char   buf[MAXBUF];
	  int multiPort = 8189;
	  bzero(&srv,sizeof(srv));
	  srv.sin_family=AF_INET;
	  srv.sin_addr.s_addr=inet_addr(multicast_addr);
	  srv.sin_port=htons(multiPort);

	  s=socket(AF_INET,SOCK_DGRAM,0);
	  if(s <0)
	  {
	    perror( "Opening   socket ");
	    return   0;
	  }
	  char netdeviceIP[MAXBUF];
	  strcpy(netdeviceIP,"eth0");
	                   getOwnIP(netdeviceIP);
	  while(1)
	  {
	    //fgets(buf,MAXBUF,stdin);

	    char hostname[MAXBUF];

		  struct hostent* h = gethostent();
		  while(h!=NULL){
		      if((strcmp(inet_ntoa(*((struct in_addr*)h->h_addr_list[0])),"127.0.0.1")==0)){
		        strcpy(hostname,inet_ntoa(*((struct in_addr*)h->h_addr_list[0])));
		        break;
		      }
		      else if(h->h_addr_list[1]==NULL){
		        strcpy(hostname,inet_ntoa(*((struct in_addr*)h->h_addr_list[1])));
		        break;
		      }
		    h=gethostent();
		  }
		  if(h==NULL){
		    strcpy(hostname,"是在没办法了:127.0.0.1");
		  }
		  endhostent();

            sprintf(buf,"%s %s %s %d",h->h_name,hostname,netdeviceIP, multiPort);
	    if(sendto(s,buf,strlen(buf),0,(struct   sockaddr*)&srv,sizeof(srv)) <0)
	    {
	      perror( "sendto ");
	      return   0;
	    }
	    else
	    {
	      fprintf(stdout, "send   to   group   %s   :   %s\n ",multicast_addr,buf);
	    }
	    sleep(15);
	  }
	  return   1;
}


void* handleclient (void* client)
{
	pclientinfo clientNode = (pclientinfo)client;
	int nread;
	struct message a;
	char buf[MAXLEN],str[MAXLEN];
	//printf("2client sockfd:%d\n",clientNode->sockfd);

	while(1)
	{
	        //printf("正在recving…………\n");
		while((nread = recv(clientNode->sockfd,&a,sizeof(a),0))<0)
		//printf("recv %d bytes %s from %s",nread,a.msg,a.name);
		  ;
		printf("recv %d bytes %s from %s with flag %s\n",nread,a.msg,a.name,a.flag);
		if(nread == 0)
		{
			strcpy(a.flag,"sermsg");
			printf("客户端%s退出\n",clientNode->name);

			pclientinfo L;
			L = clientlink;
			L=L->next;
			sprintf(buf,"客户端%s退出\n",clientNode->name);
			deletelist(clientlink ,clientNode->name);
			while(L != NULL)
			{
				send(L->sockfd,buf,strlen(buf)+1,0);
				L = L->next;
			}
			continue;

		}
		else if (strcmp(a.flag,"all") == 0)
		{
			if (strcmp(a.msg,"") != 0)
			{
			  printf("%s\n",a.msg);
				pclientinfo L;
				L = clientlink;
				L=L->next;
				strcpy(a.name,clientNode->name);
				printf("%s %s\n",a.name,a.msg);

				while(L != NULL)
				{
				  printf("%s %s\n",a.name,a.msg);
					if(L->sockfd != clientNode->sockfd)
					   send(L->sockfd,&a,sizeof(struct message),0);
					L = L->next;
				}
				printf("%s says %s\n",a.name,a.msg);
			}
			continue;
		}
		else if(strcmp(a.flag,"view") == 0)
		{
			pclientinfo L;
			int i = 1;
			L = clientlink;
			L=L->next;
			memset(buf,0,strlen(buf));
			while(L != NULL)
			{
				memset(str,0,strlen(str));
				sprintf(str,"%d$%s$%s$\n",i,L->name,inet_ntoa(L->addr_in.sin_addr));
				strcat(buf,str);
				//      send(clientNode.decr,str,strlen(str)+1,0);
				L = L->next;
				i++;
			}
			strcpy(a.name,clientNode->name);
			strcpy(a.msg,buf);

			send(clientNode->sockfd,&a,sizeof(struct message),0);
			continue;

		}
		else if(strcmp(a.flag,"login") == 0)
	                {
		               strcpy(clientNode->name,a.name);
		               insertend(clientlink,clientNode);
		               //send(clientNode.decr,buf,strlen(buf)+1,0);
		               printf("%s join the room!\n");
	                       continue;

	                }
		else if(strcmp(a.flag,"private") == 0)
		{
			pclientinfo L;
			L = clientlink;
			L=L->next;
			//sprintf(buf,"%s:%s\n",clientNode.name,a.msg);
			strcpy(a.name,clientNode->name);
			while(L != NULL)
			{
				if (strcmp(L->name,a.flag) == 0)
				{
					//send(L->data.decr,buf,strlen(buf)+1,0);
					send(L->sockfd,&a,sizeof(struct message),0);
					break;
				}
				L = L->next;
			}
			continue;
		}

        }
}

void* handleaccept(void *serverfd)
{

	while(1)
	{
	        socklen_t client_len;
	        int sockfd = *(int*)serverfd;
	        pclientinfo clientNode = (pclientinfo)malloc(sizeof(clientinfo));
	        struct sockaddr_in client_addr;
	        printf("正在handleaccept…………\n");
		client_len =sizeof(struct sockaddr_in);
		if((clientNode->sockfd = accept(sockfd,(struct sockaddr *)&client_addr,&client_len)) == -1)
		{
			printf("接收连接失败\n");
		}
		else
		{
			printf("与%s:%d连接建立成功\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
			clientNode->addr_in = client_addr;
			pthread_create(&clientNode->pid,NULL,(void *)handleclient,(void *)clientNode);
			//printf("1client sockfd:%d\n",clientNode->sockfd);
		}
	}
}
